/*   
 * Copyright (c) 2010-2020 Founder Ltd. All Rights Reserved.   
 *   
 * This software is the confidential and proprietary information of   
 * Founder. You shall not disclose such Confidential Information   
 * and shall use it only in accordance with the terms of the agreements   
 * you entered into with Founder.   
 *   
 */
package com.wujw.auto.generate.impl;

import java.io.File;
import java.util.List;

import com.wujw.auto.bean.ColumnStruct;
import com.wujw.auto.bean.TableStruct;
import com.wujw.auto.generate.GenerateMapper;
import com.wujw.auto.generate.GetTableDao;
import com.wujw.auto.utils.ConfigUtil;
import com.wujw.auto.utils.DataTypeUtil;
import com.wujw.auto.utils.FileUtil;
import com.wujw.auto.utils.JDBCTypeUtil;
import com.wujw.auto.utils.NameUtil;

/**
 * This class is used for ...
 * 
 * @author wujw
 * @version 1.0, 2017年11月11日
 */
public class GenerateMapperImpl implements GenerateMapper {

    // 获取表结构信息
    GetTableDao getTableDao = new GetTablesDaoImpl();
    List<TableStruct> list = getTableDao.getTablesStruct();
     
    //TODO
    //Criteria
    private final static String PARAMATE_CRITERIA="Criteria";
    
    /**
     * conditions
     */
    private final static String SELECT_OR_COUNT_CONDITION="SelectOrCountcondition";
    
    
    @Override
    public boolean createMapperXml() {
        /* =======获取配置文件的信息 ==== */

        // 是否生成
        boolean mapperXmlFlag = ConfigUtil.mapperXmlFlag;
        if (mapperXmlFlag) {
            // 项目的路径
            String projectPath = ConfigUtil.projectPath;
            // mapper包名
            String mapperXmlPackage = ConfigUtil.mapperXmlPackage;
            // bean 包名
            String beanPackage = ConfigUtil.beanPackage;
            // dao 接口包名 ===== 如果命名空间是接口，需要用到
            //String daoPackage = ConfigUtil.daoPackage;

            // mapper包名转换路径
            String mapperXmlPath = mapperXmlPackage.replace(".", File.separator);
            // mapper.xml的路径
            String path = projectPath + File.separator+"src"+File.separator+"main"+File.separator+"resources"+ File.separator+ mapperXmlPath;

            // 遍历表结构
            for (int i = 0; i < list.size(); i++) {
                String tableName = list.get(i).getTableName();
                System.out.println(tableName + " >>>>>>>>> Mapperxml开始生成");

                // 文件名 ---与bean处理方式相同，如果可以的话，可在配置文件中加入配置 TODO
                String fileName = NameUtil.fileName(tableName);
                String beanName = NameUtil.fileName(tableName);// 此处一致bean
                // 获得所有的表结构
                List<ColumnStruct> columns = list.get(i).getColumns();
                // TODO 主键

                // 文件内容
                StringBuffer headContent = new StringBuffer();
                headContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
                headContent.append(
                        "<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n");

                // 命名空间 暂用bean,如需mapper代理也可改成接口路径
                headContent.append("<mapper namespace=\"" + beanPackage + "." + beanName + "\">\n");

                // resultMap
                StringBuffer resultMapContent = new StringBuffer();
                //resultMap的id内容为bean名的首字母小写
                String resultMapId = beanName.substring(0, 1).toLowerCase()+beanName.substring(1);
                
                resultMapContent.append("\t" + "<resultMap type=\"" + beanPackage + "." + beanName + "\" id=\""+ resultMapId +"\">\n");
                
                
                /*<==========================INSERT START==================================>*/
                //insert 定义的列名    ----------INSERT INTO T_NAME (
                StringBuffer insertContent = new StringBuffer();
                insertContent.append("\t"+"<insert id=\"insert\" parameterType=\""+beanPackage+"."+beanName+"\">\n");
                insertContent.append("\t\t"+"INSERT INTO "+tableName.toUpperCase()+"(\n");
                
                //VALUES(
                StringBuffer insertContentValues = new StringBuffer();
                insertContentValues.append("\t\t"+"VALUES(\n");
                
                StringBuffer updateContent = new StringBuffer();
                updateContent.append("\t"+"<update id=\"update\" parameterType=\""+beanPackage+"."+beanName+"\">\n");
                updateContent.append("\t\t"+"UPDATE "+tableName.toUpperCase()+"\n");
                updateContent.append("\t\t"+"<set>\n");
                
                //遍历表结构中的信息
                for (int j = 0; j < columns.size(); j++) {
                    //数据库字段名
                    String columnName = columns.get(j).getColumnName();
                    //属性名
                    String attributeName = NameUtil.columnName(columnName);
                    //字段类型
                    String dataType = DataTypeUtil.getType(columns.get(j).getDateType());
                    String jdbcType = JDBCTypeUtil.getJDBCType(dataType);
                    
                    //添加resultMap中的column
                    resultMapContent.append("\t\t"+"<result column=\""+columnName.toUpperCase()+"\" property=\""+attributeName+"\"/>\n");
                    String point = "";
                    if(j==columns.size()-1) {
                        point = "\n";
                    }else {
                        point = ",\n";
                    }
                    //动态sql列定义
                    insertContent.append("\t\t\t"+"<if test=\""+attributeName+" != null\" >\n"+"\t\t\t\t"+columnName+point+"\t\t\t"+"</if>\n");
                    //动态sql值定义
                    insertContentValues.append("\t\t\t"+"<if test=\""+attributeName+" != null\" >\n"+"\t\t\t\t"+"#{"+attributeName+"}"+point+"\t\t\t"+"</if>\n");
                    
                    if(j==columns.size()-1){
                        updateContent.append("\t\t\t"+"<if test=\""+attributeName+" != null\" >\n"+"\t\t\t"+columnName+" = "+"#{"+attributeName+"}\n\t\t\t"+"</if>\n");
                    }else{
                        updateContent.append("\t\t\t"+"<if test=\""+attributeName+" != null\" >\n"+"\t\t\t"+columnName+" = "+"#{"+attributeName+"},\n\t\t\t"+"</if>\n");   
                    }
                    
                }
                insertContent.append("\t\t\t"+")\n");
                insertContentValues.append("\t\t\t"+")\n"+"\t"+"</insert>\n");
                
                updateContent.append("\t\t\t"+"WHERE ID = #{id}");
                updateContent.append("\t\t\t"+"\n"+"\t"+"</update>\n");
                /*<==========================INSERT END==================================>*/
                
                
                /**
                 * to be complete
                 */
                /*<==========================SQLAREAR DEFINITION START==================================>*/

                StringBuffer selectAreaCondition=new StringBuffer();
                selectAreaCondition.append("\t"+ "<sql id=\""+SELECT_OR_COUNT_CONDITION+"\"> \n");
//                StringBuffer selectOrCountContent=new StringBuffer();
                for (int j = 0; j < columns.size(); j++) {
                    //数据库字段名
                    String columnName = columns.get(j).getColumnName();
                    //属性名
                    String attributeName = NameUtil.columnName(columnName);
                    //字段类型
                    //String dataType = DataTypeUtil.getType(columns.get(j).getDateType());
                    //String jdbcType = JDBCTypeUtil.getJDBCType(dataType);
                
                    //动态sql列定义
                    selectAreaCondition.append("\t\t\t"+"<if test=\""+attributeName+" != null\" >"+" AND "+ columnName.toUpperCase() +" = #{"+attributeName+"} "+"</if>\n");
                }
                selectAreaCondition.append("\t"+"</sql>\n");
                
                /*<==========================SQLAREAR DEFINITION END==================================>*/

                
                
                /*<==========================SELECT START==================================>*/
                StringBuffer selectContent=new StringBuffer();
                selectContent.append("\t"+"<select id=\"select\"  parameterType=\""+PARAMATE_CRITERIA+"\" resultMap=\""+resultMapId+"\">\n");
                selectContent.append("\t\t"+ "SELECT * FROM "+tableName.toUpperCase()+"\n"+"\t\t"+"<where>\n"+"\t\t\t"+"DELETED = '0'  \n");
                selectContent.append("\t\t\t"+"<include refid=\""+SELECT_OR_COUNT_CONDITION+"\"></include>\n");
                selectContent.append("\t\t"+"</where>\n");
                selectContent.append("\t"+"</select>\n");
                /*<==========================SELECT END==================================>*/
                
                /*<==========================COUNT START==================================>*/
                StringBuffer countContent=new StringBuffer();
                countContent.append("\t"+"<select id=\"count\"  parameterType=\""+PARAMATE_CRITERIA+"\" resultMap=\""+resultMapId+"\">\n");
                countContent.append("\t\t"+ "SELECT COUNT(*) FROM "+tableName.toUpperCase()+"\n"+"\t\t"+"<where>\n"+"\t\t\t"+"DELETED = '0' \n ");
                countContent.append("\t\t\t"+"<include refid=\""+SELECT_OR_COUNT_CONDITION+"\"></include>\n");
                countContent.append("\t\t"+"</where>\n");
                countContent.append("\t"+"</select>\n");
                /*<==========================COUNT END==================================>*/
                
                /*===========================DELETE START===============================*/
                StringBuffer deleteContent = new StringBuffer();
                deleteContent.append("\t"+"<update id=\"delete\" parameterType=\""+PARAMATE_CRITERIA+"\">\n");
                deleteContent.append("\t\t"+ "UPDATE "+ tableName.toUpperCase() + " SET DELETED = '1' \n"+"\t\t"+"<where>\n");
                deleteContent.append("\t\t\t"+"<include refid=\""+SELECT_OR_COUNT_CONDITION+"\"></include>\n");
                deleteContent.append("\t\t"+"</where>\n");
                deleteContent.append("\t"+"</update>\n");
                /*===========================DELETE END===============================*/
                
                
                /*=======================LOAD START =========================*/
                StringBuffer loadContent = new StringBuffer();
                loadContent.append("\t"+"<select id=\"load\" parameterType='String' resultMap=\""+resultMapId+"\">\n");
                loadContent.append("\t\t"+"SELECT * FROM "+tableName.toUpperCase()+" WHERE ID = #{id} \n");
                loadContent.append("\t" + "</select>\n");
                /*=======================LOAD END =========================*/
                
                
                
                
                //拼接
                StringBuffer content = new StringBuffer();
                //xml头文件
                content.append(headContent);
                //resultMap
                content.append(resultMapContent);
                content.append("\t"+"</resultMap>\n");
                //insert content 
                content.append(insertContent);
                content.append(insertContentValues);
                //select content
                content.append(selectContent);
                //count count
                content.append(countContent);
                //
                content.append(deleteContent);
                content.append(updateContent);
                content.append(loadContent);
                
                //sql condition content
                content.append(selectAreaCondition);
                
                content.append("</mapper>");
                
                FileUtil.createFileAtPath(path+File.separator,fileName+".xml" ,content.toString());
                System.out.println(tableName + " >>>>>>>>> Mapperxml生成完毕");
            }
            return true;

        }

        return false;
    }

}
